This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.
When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
# Load necessary libraries
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.3
library(gganimate)
## Warning: package 'gganimate' was built under R version 4.3.3
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# Set constants
amplitude <- 10
amplitude_1 <- 5
amplitude_2 <- 2
duration <- 2
freq_1 <- 4
freq_2 <- 100
sample_rate <- 400
lowFreq <- 20
highFreq <- 41
time_gl <- seq(0, duration, 1/sample_rate)
# Function to generate signal, FFT, and inverse FFT
generate_signal_fft <- function(frequency) {
primary_signal <- amplitude * sin(pi * frequency * time_gl)
signal_1 <- amplitude_1 * sin(pi * freq_1 * time_gl)
signal_2 <- amplitude_2 * sin(pi * freq_2 * time_gl)
combined_signal <- primary_signal + signal_1 + signal_2
# Perform FFT
signal_yfft <- fft(combined_signal)
pow_spectrum <- abs(signal_yfft)
n <- length(signal_yfft)
# Remove stationary frequencies
signal_yfft[c(freq_1, freq_2, n - freq_1 + 1, n - freq_2 + 1)] <- 0
# Perform inverse FFT
signal_yInvfft <- Re(fft(signal_yfft, inverse = TRUE)) / n
list(original = combined_signal,
power_spectrum = pow_spectrum,
filtered = signal_yInvfft)
}
# Create empty data frames for animation
original_data <- data.frame()
power_data <- data.frame()
inverse_data <- data.frame()
# Generate data for each frequency step
for (freqID in seq(lowFreq, highFreq)) {
results <- generate_signal_fft(freqID)
# Accumulate data for animation
original_data <- rbind(original_data,
data.frame(time = time_gl,
signal = results$original,
frequency = freqID))
power_data <- rbind(power_data,
data.frame(time = seq(0, 200, length.out = length(results$power_spectrum)),
signal = results$power_spectrum[1:length(results$power_spectrum)],
frequency = freqID))
inverse_data <- rbind(inverse_data,
data.frame(time = time_gl,
signal = results$filtered,
frequency = freqID))
}
# Create the animated plots
# No need to wrap in ggplot, just create frames for the animation
original_animation <- ggplot(original_data, aes(x = time, y = signal)) +
geom_line(color = "red") +
labs(title = "Original Combined Signal: {frame_time}", x = "Time (s)", y = "Amplitude") +
theme_minimal() +
ylim(-20, 20) +
transition_time(frequency)
original_animation
power_animation <- ggplot(power_data, aes(x = time, y = signal)) +
geom_line(color = "blue") +
labs(title = "Power Spectrum: {frame_time}", x = "Frequency Bin", y = "Magnitude") +
theme_minimal() +
ylim(0, max(power_data$signal)) +
transition_time(frequency)
power_animation
inverse_animation <- ggplot(inverse_data, aes(x = time, y = signal)) +
geom_line(color = "orange") +
labs(title = "Inverse FFT Signal: {frame_time}", x = "Time (s)", y = "Amplitude") +
theme_minimal() +
ylim(-20, 20) +
transition_time(frequency)
inverse_animation